package com.liwen.service.pool;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author: li.rui
 * @time: 2018-05-21 14:38
 * @description:
 */
public class SessionPoolFactory implements PooledObjectFactory<SessionObj> {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    private long idleMills;
    private AbstractFtpClient client;

    public SessionPoolFactory(AbstractFtpClient client, long idleMills) throws Exception {
        this.client = client;
        this.idleMills = idleMills;
    }

    @Override
    public PooledObject<SessionObj> makeObject() throws Exception {
        Session session = client.getJsch().getSession(client.getUser(), client.getHost(), client.getPort());
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();
        Channel channel = session.openChannel("sftp");
        channel.connect();
        SessionObj obj = new SessionObj(session, (ChannelSftp) channel);
        log.info("makeObject=thread:{}", Thread.currentThread().getName());
        return new DefaultPooledObject<>(obj);
    }

    @Override
    public void destroyObject(PooledObject<SessionObj> p) throws Exception {
        SessionObj obj = p.getObject();
        obj.getSftp().quit();
        obj.getSftp().disconnect();
        obj.getSession().disconnect();
        log.info("destroyObject=thread:{}", Thread.currentThread().getName());
    }

    @Override
    public boolean validateObject(PooledObject<SessionObj> p) {
        log.info("validateObject=thread:{},idle:{},maxIdle:{}", Thread.currentThread().getName(), p.getIdleTimeMillis(), idleMills);
        if (p.getIdleTimeMillis() > idleMills)
            return false;
        if (!p.getObject().getSession().isConnected())
            return false;
        return true;
    }

    @Override
    public void activateObject(PooledObject<SessionObj> p) throws Exception {
    }

    @Override
    public void passivateObject(PooledObject<SessionObj> p) throws Exception {
    }
}
